home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-04-28 | 9.6 KB | 452 lines | [TEXT/MPS ] |
- #ifndef __CDENT__
- #include "cdent.h"
- #endif
-
- #ifndef __FORMATLOG__
- #include "FormatLog.h"
- #endif
-
- #ifndef __FORMATTING__
- #include "Formatting.h"
- #endif
-
- #ifndef __SYNTACTIC__
- #include "Syntactic.h"
- #endif
-
- #ifndef __OSUTILS__
- #include <osutils.h>
- #endif
-
-
-
- /*µ class CheckpointItem
- ** A CheckpointItem is an element of the FormatLog queue. It acts as a wrapper
- ** for the Formatting action itself. The class is abstract because the action
- ** method, "Perform", must be overridden. Also, operator new is overridden to
- ** use the queue for allocation.
- ** A caveat: the overridden Size() and Perform() methods must not expect "this"
- ** to remain unchanged as the object is being invoked in a handle. You've been
- ** warned.
- */
- #pragma segment FormatLog
- class CheckpointItem : public SingleObject {
- public:
- CheckpointItem();
-
- virtual void Perform(Formatting *aFormat) = 0;
- // Abstract operation. Perform() performs the action associated with
- // each item using the information in aFormat to perform the
- // requested operation.
-
- virtual size_t Size() const = 0;
- // Return the size of the item in the queue. Used by FormatLog::Redo
- // to advance Next() and fNextRedo.
-
- void *operator new(size_t);
- void *operator new(size_t aSize, DataArea *anArea);
- inline void operator delete(void *);
- /*
- ** Override new. The default method is overridden so that an error
- ** occurs should anyone use it. The DataArea* method is the new that
- ** allocates out of a data area and the one which should be used
- */
-
-
- private:
- // No variables in root abstract class
- };
-
-
- // µ CheckpointItem::CheckpointItem
- #pragma segment FormatLog
- inline CheckpointItem::CheckpointItem()
- {
- }
-
-
- // µ CheckpointItem::operator delete
- #pragma segment FormatLog
- inline void CheckpointItem::operator delete(void *)
- {
- }
-
-
-
- /*µ class CheckpointMethod
- ** This class wraps pure method calls.
- */
- #pragma segment FormatLog
- class CheckpointMethod : public CheckpointItem {
- public:
- CheckpointMethod(void(Formatting::*aMethod)());
- virtual void Perform(Formatting *aFormat);
- virtual size_t Size() const;
-
- private:
- void(Formatting::*fMethod)();
- };
-
-
- // µ CheckpointMethod::CheckpointMethod
- #pragma segment FormatLog
- inline CheckpointMethod::CheckpointMethod(void(Formatting::*aMethod)())
- : fMethod(aMethod)
- {
- }
-
-
- // µ CheckpointMethod::Perform
- #pragma segment FormatLog
- void CheckpointMethod::Perform(Formatting *aFormat)
- {
- (aFormat->*fMethod)();
- }
-
-
- // µ CheckpointMethod::Size
- #pragma segment FormatLog
- size_t CheckpointMethod::Size() const
- {
- return (sizeof(*this));
- }
-
-
-
- /*µ class CheckpointGlue
- ** This class wraps glue items and the method used to invoke them
- */
- #pragma segment FormatLog
- class CheckpointGlue : public CheckpointItem {
- public:
- CheckpointGlue(void(Formatting::*aMethod)(FormatString), FormatString aGlue);
-
- virtual void Perform(Formatting *aFormat);
- virtual size_t Size() const;
-
- private:
- void(Formatting::*fMethod)(FormatString);
- FormatString fGlue;
- };
-
-
- // µ CheckpointGlue::CheckpointGlue
- #pragma segment FormatLog
- inline CheckpointGlue::CheckpointGlue(void(Formatting::*aMethod)(FormatString), FormatString aGlue)
- : fMethod(aMethod),
- fGlue(aGlue)
- {
- }
-
-
- // µ CheckpointGlue::Perform
- #pragma segment FormatLog
- void CheckpointGlue::Perform(Formatting *aFormat)
- {
- (aFormat->*fMethod)(fGlue);
- }
-
-
- // µ CheckpointGlue::Size
- #pragma FormatLog
- size_t CheckpointGlue::Size() const
- {
- return (sizeof(*this));
- }
-
-
-
- /*µ class CheckpointSyntactic
- ** This class wraps tokens and the method used to invoke them
- */
- #pragma segment FormatLog
- class CheckpointSyntactic : public CheckpointItem {
- public:
- CheckpointSyntactic(void(Formatting::*aMethod)(Syntactic *), Syntactic *aToken);
-
- virtual void Perform(Formatting *aFormat);
- virtual size_t Size() const;
- private:
- void(Formatting::*fMethod)(Syntactic *);
- Syntactic *fToken;
- };
-
-
- // µ CheckpointSyntactic::CheckpointSyntactic
- #pragma segment FormatLog
- inline CheckpointSyntactic::CheckpointSyntactic(void(Formatting::*aMethod)(Syntactic *), Syntactic *aToken)
- : fMethod(aMethod),
- fToken(aToken)
- {
- fMethod = aMethod;
- fToken = aToken;
- }
-
-
- // µ CheckpointSyntactic::Perform
- #pragma segment FormatLog
- void CheckpointSyntactic::Perform(Formatting *aFormat)
- {
- (aFormat->*fMethod)(fToken);
- }
-
-
- // µ CheckpointSyntactic::Size
- #pragma segment FormatLog
- size_t CheckpointSyntactic::Size() const
- {
- return (sizeof(*this));
- }
-
-
-
- /*µ class CheckpointBoolean
- ** This class wraps tokens and the method used to invoke them
- */
- #pragma segment FormatLog
- class CheckpointBoolean : public CheckpointItem {
- public:
- CheckpointBoolean(void(Formatting::*aMethod)(Boolean), Boolean isGroup);
-
- virtual void Perform(Formatting *aFormat);
- virtual size_t Size() const;
-
- private:
- void(Formatting::*fMethod)(Boolean);
- Boolean fIsGroup;
- };
-
-
- // µ CheckpointBoolean::CheckpointBoolean
- #pragma segment FormatLog
- inline CheckpointBoolean::CheckpointBoolean(void(Formatting::*aMethod)(Boolean), Boolean isGroup)
- {
- // Initialize the variables
- fMethod = aMethod;
- fIsGroup = isGroup;
- }
-
-
- // µ CheckpointBoolean::Perform
- #pragma segment FormatLog
- void CheckpointBoolean::Perform(Formatting *aFormat)
- {
- (aFormat->*fMethod)(fIsGroup);
- }
-
-
- // µ CheckpointBoolean::Size
- #pragma segment FormatLog
- size_t CheckpointBoolean::Size() const
- {
- return (sizeof(*this));
- }
-
-
-
-
-
-
- /*
- ** Method implementation
- */
-
-
- //µ FormatLog::~FormatLog
- #pragma segment FormatLog
- FormatLog::~FormatLog()
- {
- if (fContext)
- DisposHandle(fContext);
- }
-
-
- //µ FormatLog::IFormatLog
- #pragma segment FormatLog
- short FormatLog::IFormatLog()
- {
- short anErr;
-
- // Allow Record() to work
- fState = kRecording;
- fNextRedo = 0;
- fCheckpoint = 0;
-
- anErr = fLog.IDataArea(64, 64); // Just a guess.
- if (anErr != noErr)
- return (anErr);
-
- anErr = fSavedContexts.IDataArea(64, 64);
- if (anErr != noErr)
- return (anErr);
-
- fContext = NewHandle(sizeof(FContext));
- return (fContext ? noErr : MemError());
- }
-
-
- // µ FormatLog::IFormatLog
- #pragma segment FormatLog
- short FormatLog::IFormatLog(const FormatLog *aFormatLog)
- {
- short anErr;
-
- fNextRedo = aFormatLog->fNextRedo;
- fCheckpoint = aFormatLog->fCheckpoint;
- fContext = aFormatLog->fContext;
-
- anErr = fLog.IDataArea(&aFormatLog->fLog);
- if (anErr != noErr)
- return (anErr);
-
- anErr = fSavedContexts.IDataArea(&aFormatLog->fSavedContexts);
- if (anErr != noErr)
- return (anErr);
-
- if (fContext)
- return (HandToHand(&fContext));
-
- return (noErr);
- }
-
-
- //µ FormatLog::Record
- #pragma segment FormatLog
- void FormatLog::Record(void(Formatting::*aMethod)())
- {
- if (fState == kRecording)
- new(&fLog)CheckpointMethod(aMethod);
- }
-
-
- // µ FormatLog::Record
- #pragma segment FormatLog
- void FormatLog::Record(void(Formatting::*aMethod)(FormatString), FormatString aGlue)
- {
- if (fState == kRecording)
- new(&fLog)CheckpointGlue(aMethod, aGlue);
- }
-
-
- // µ FormatLog::Record
- #pragma segment FormatLog
- void FormatLog::Record(void(Formatting::*aMethod)(Syntactic *), Syntactic *aToken)
- {
- if (fState == kRecording)
- new(&fLog)CheckpointSyntactic(aMethod, aToken);
- }
-
-
- // µ FormatLog::Record
- #pragma segment FormatLog
- void FormatLog::Record(void(Formatting::*aMethod)(Boolean), Boolean isGroup)
- {
- if (fState == kRecording)
- new(&fLog)CheckpointBoolean(aMethod, isGroup);
- }
-
-
- //µ FormatLog::RecordDepth
- #pragma segment FormatLog
- void FormatLog::RecordDepth(int aDepth)
- {
- if (fState == kRecording)
- if (aDepth < fMinDepth)
- fMinDepth = aDepth;
- else if (aDepth > fMaxDepth)
- fMaxDepth = aDepth;
- }
-
-
- //µ FormatLog::Checkpoint
- #pragma segment FormatLog
- void FormatLog::Checkpoint(const FContext *aContext, const DataArea *savedContexts, int aDepth)
- {
- // Allow Record() to work
- EnableRecord();
-
- // The context might have changed
- **(FContext * *)fContext = *aContext;
-
- // Record the depth
- fMinDepth = fMaxDepth = aDepth;
-
- // If no commands have been added, then savedContexts has not changed
- // since the last call. Return immediately.
- if (fCheckpoint == Next())
- return;
-
- // Save the data from the savedContexts stack into our area.
- fSavedContexts.Assign(savedContexts);
-
- // Reset fLog, set fCheckpoint to the where the next Record() will
- // drop its data.
- fLog.SetCursor(0);
- fCheckpoint = Next();
- }
-
-
- //µ FormatLog::Rollback
- #pragma segment FormatLog
- void FormatLog::Rollback(FContext *aContext, DataArea *savedContexts)
- {
- // Disable Record()
- fState = kRedoing;
-
- // Position to the saved checkpoint marker
- fNextRedo = fCheckpoint;
-
- // Restore the data from fSavedContexts into savedContexts.
- *aContext = **(FContext * *)fContext;
- savedContexts->Assign(&fSavedContexts);
- }
-
-
- //µ FormatLog::Redo
- #pragma segment FormatLog
- Boolean FormatLog::Redo(Formatting *aFormat)
- {
- // Check that there is something to execute.
- if (fNextRedo >= Next() || fState != kRedoing)
- return (false);
-
- // Get the next item from the queue and advance past it
- CheckpointItem * anItem = (CheckpointItem *)fLog.GetData(fNextRedo);
- fNextRedo += anItem->Size();
-
- // Execute it. Notice that fLog is not locked as "Perform" goes in and
- // out without referring to "this" after the pointer to method and any
- // arguments have been referenced.
- anItem->Perform(aFormat);
- return (true);
- }
-
-
- //µ CheckpointItem::operator new
- #pragma segment FormatLog
- void *CheckpointItem::operator new(size_t aSize, DataArea *anArea)
- {
- // Check that there is space available in the queue. If not, die the
- // horrible death.
- if (anArea->Require(aSize) < aSize) {
- diag(kFatal, "Out of memory - CheckpointItem::operator new\n");
- return (0);
- }
-
- // Return a pointer and advance the cursor
- void *aPtr = anArea->GetData();
- anArea->IncrCursor(aSize);
- return (aPtr);
- }
-
-
- // µ CheckpointItem::operator
- #pragma segment FormatLog
- void *CheckpointItem::operator new(size_t)
- {
- diag(kFatal, "Internal error: Checkpoint::operator new(size_t) called\n");
- return (0);
- }
-
-
-